{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Sweeps - Eigenmode matrix"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prerequisite\n",
    "You need to have a working local installation of Ansys"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Perform the necessary imports and create a QDesign in Metal first."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import qiskit_metal as metal\n",
    "from qiskit_metal import designs, draw\n",
    "from qiskit_metal import MetalGUI, Dict, Headings\n",
    "from qiskit_metal.analyses.quantization import EPRanalysis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Create the design in Metal\n",
    "# Create a design by specifying the chip size and open Metal GUI.\n",
    "\n",
    "design = designs.DesignPlanar({}, True)\n",
    "design.chips.main.size['size_x'] = '2mm'\n",
    "design.chips.main.size['size_y'] = '2mm'\n",
    "\n",
    "gui = MetalGUI(design)\n",
    "\n",
    "from qiskit_metal.qlibrary.qubits.transmon_pocket import TransmonPocket\n",
    "from qiskit_metal.qlibrary.terminations.open_to_ground import OpenToGround\n",
    "from qiskit_metal.qlibrary.tlines.meandered import RouteMeander"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### In this example, the design consists of 1 qubit and 1 CPW connected to OpenToGround."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Allow running the same cell here multiple times to overwrite changes\n",
    "design.overwrite_enabled = True\n",
    "\n",
    "# Remove all qcomponents from GUI.\n",
    "design.delete_all_components()\n",
    "\n",
    "# So as to demonstrate the quality factor outputs easily, the\n",
    "#subtrate material type is being changed to FR4_epoxy from the\n",
    "#default of silicon\n",
    "design.chips.main.material = 'FR4_epoxy'\n",
    "\n",
    "q1 = TransmonPocket(\n",
    "    design,\n",
    "    'Q1',\n",
    "    options=dict(pad_width='425 um',\n",
    "                 pocket_height='650um', \n",
    "                 hfss_inductance = '17nH',\n",
    "                 connection_pads=dict(\n",
    "                     readout=dict(loc_W=+1, loc_H=+1, pad_width='200um'))))\n",
    "otg = OpenToGround(design,\n",
    "                   'open_to_ground',\n",
    "                   options=dict(pos_x='1.75mm', pos_y='0um', orientation='0'))\n",
    "readout = RouteMeander(\n",
    "    design, 'readout',\n",
    "    Dict(\n",
    "        total_length='6 mm',\n",
    "        hfss_wire_bonds = True,\n",
    "        fillet='90 um',\n",
    "        lead=dict(start_straight='100um'),\n",
    "        pin_inputs=Dict(start_pin=Dict(component='Q1', pin='readout'),\n",
    "                        end_pin=Dict(component='open_to_ground', pin='open')),\n",
    "    ))\n",
    "\n",
    "gui.rebuild()\n",
    "gui.autoscale()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 Metal passes information to 'hfss' simulator, and gets a solution matrix.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Create a separate analysis object for the combined qbit+readout.\n",
    "eig_qres = EPRanalysis(design, \"hfss\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Prepare data to pass as arguments for method run_sweep().  \n",
    "\n",
    "Method run_sweep() will open the simulation software if software is not open already."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "### for render_design()\n",
    "# Render every QComponent in QDesign.\n",
    "render_qcomps = []\n",
    "\n",
    "# Identify which kind of pins in Ansys. \n",
    "# Follow details from renderer in\n",
    "# QHFSSRenderer.render_design.\n",
    "# No pins are open, so don't need to utilize render_endcaps.\n",
    "open_terminations = []\n",
    "\n",
    "#List of tuples of jj's that shouldn't be rendered.  \n",
    "#Follow details from renderer in QHFSSRenderer.render_design.\n",
    "render_ignored_jjs = []\n",
    "\n",
    "# Either calculate a bounding box based on the location of \n",
    "# rendered geometries or use chip size from design class.\n",
    "box_plus_buffer = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# For simulator hfss, the setup options are :\n",
    "# min_freq_ghz, n_modes, max_delta_f, max_passes, min_passes, min_converged=None,\n",
    "# pct_refinement, basis_order\n",
    "\n",
    "# If you don't pass all the arguments, the default is determined by \n",
    "# QHFSSRenderer's default_options.\n",
    "\n",
    "# If a setup named \"sweeper_em_setup\" exists in the project, it will be deleted, \n",
    "# and a new setup will be added.\n",
    "\n",
    "eig_qres.sim.setup.name=\"sweeper_em_setup\"\n",
    "eig_qres.sim.setup.min_freq_ghz=4\n",
    "eig_qres.sim.setup.n_modes=2\n",
    "eig_qres.sim.setup.max_passes=15\n",
    "eig_qres.sim.setup.min_converged = 2\n",
    "eig_qres.sim.setup.max_delta_f = 0.2\n",
    "\n",
    "eig_qres.setup.junctions.jj.rect = 'JJ_rect_Lj_Q1_rect_jj'\n",
    "eig_qres.setup.junctions.jj.line = 'JJ_Lj_Q1_rect_jj_'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### - Connect to Ansys HFSS, eigenmode solution.\n",
    "### - Rebuild QComponents in Metal.\n",
    "### - Render QComponents within HFSS and setup.\n",
    "### - Delete/Clear the HFSS between each calculation of solution matrix.\n",
    "### - Calculate solution matrix for each value in option_sweep.\n",
    "\n",
    "#### Return a dict and return code.  If the return code is zero, there were no errors detected.  \n",
    "#### The dict has:  key = each value used to sweep, value = data from simulators\n",
    "\n",
    "#### This could take minutes based size of design."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Note: The method will connect to Ansys, activate_eigenmode_design(), add_eigenmode_setup().\n",
    "\n",
    "all_sweeps, return_code = eig_qres.run_sweep(readout.name,\n",
    "                                        'total_length', \n",
    "                                        ['10mm', '11mm', '12mm'],\n",
    "                                        render_qcomps,\n",
    "                                        open_terminations,\n",
    "                                         ignored_jjs=render_ignored_jjs,\n",
    "                                        design_name=\"GetEigenModeSolution\", \n",
    "                                       box_plus_buffer=box_plus_buffer\n",
    "                                      )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_sweeps.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# For example, just one group of solution data.\n",
    "all_sweeps['10mm'].keys()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_sweeps['10mm']\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_sweeps['10mm']['variables']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_sweeps['10mm']['sim_variables']['convergence_t']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_sweeps['10mm']['sim_variables']['convergence_f']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Uncomment the next close simulation software. \n",
    "#eig_qres.sim.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Uncomment next line if you would like to close the gui\n",
    "#gui.main_window.close()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
